<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="theme-color" content="#0078E7"><meta name="author" content="爱肖彤真是太好了"><meta name="copyright" content="爱肖彤真是太好了"><meta name="generator" content="Hexo 5.1.1"><meta name="theme" content="hexo-theme-yun"><title>fastapi基础 | 工藤旧二の博客</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@900&amp;display=swap" media="none" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/star-markdown-css@0.1.19/dist/yun/yun-markdown.min.css"><script src="//at.alicdn.com/t/font_1140697_stqaphw3j4.js" async></script><script src="https://cdn.jsdelivr.net/npm/scrollreveal/dist/scrollreveal.min.js" defer></script><script>document.addEventListener("DOMContentLoaded", () => {
  [".post-card",".post-content img"].forEach((target)=> {
    ScrollReveal().reveal(target);
  })
});
</script><link rel="shortcut icon" type="image/svg+xml" href="/task/yun.ico"><link rel="mask-icon" href="/task/yun.ico" color="#0078E7"><link rel="alternate icon" href="/yun.ico"><link rel="preload" href="/task/css/hexo-theme-yun.css" as="style"><link rel="preload" href="/task/js/utils.js" as="script"><link rel="preload" href="/task/js/hexo-theme-yun.js" as="script"><link rel="prefetch" href="/task/js/sidebar.js" as="script"><link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin><link rel="stylesheet" href="/task/css/hexo-theme-yun.css"><link rel="alternate" href="/task/atom.xml" title="工藤旧二の博客" type="application/atom+xml"><script id="yun-config">
    const Yun = window.Yun || {};
    window.CONFIG = {"root":"/task/","title":"工藤旧二の博客","version":"0.9.7","anonymous_image":"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg","say":{"api":"https://v1.hitokoto.cn","hitokoto":true},"local_search":{"path":"/task/search.xml"},"fireworks":{"colors":["102, 167, 221","62, 131, 225","33, 78, 194"]}};
  </script><script>(function(){
  var bp = document.createElement('script');
  var curProtocol = window.location.protocol.split(':')[0];
  if (curProtocol === 'https') {
    bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
  }
  else {
    bp.src = 'http://push.zhanzhang.baidu.com/push.js';
  }
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(bp, s);
})();</script><meta name="description" content="入门安装基础依赖pip install fastapi 并且安装uvicorn来作为服务器： pip install uvicorn[standard] 然后对你想使用的每个可选依赖项也执行相同的操作 启动服务uvicorn main:app --reload uvicorn main:app 命令含义如下:  main：main.py 文件（一个 Python「模块」）。 app：在 main.">
<meta property="og:type" content="article">
<meta property="og:title" content="fastapi基础">
<meta property="og:url" content="http://huang_zhao.gitee.io/task/2021/07/02/python/%E6%A1%86%E6%9E%B6/fast-api/fastapi%20%E5%9F%BA%E7%A1%80/index.html">
<meta property="og:site_name" content="工藤旧二の博客">
<meta property="og:description" content="入门安装基础依赖pip install fastapi 并且安装uvicorn来作为服务器： pip install uvicorn[standard] 然后对你想使用的每个可选依赖项也执行相同的操作 启动服务uvicorn main:app --reload uvicorn main:app 命令含义如下:  main：main.py 文件（一个 Python「模块」）。 app：在 main.">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-07-02T05:33:43.000Z">
<meta property="article:modified_time" content="2021-07-01T06:11:51.000Z">
<meta property="article:author" content="爱肖彤真是太好了">
<meta property="article:tag" content="python">
<meta property="article:tag" content="框架">
<meta property="article:tag" content="fastapi">
<meta name="twitter:card" content="summary"><script src="/task/js/ui/mode.js"></script><link rel="stylesheet" href="/task/css/prism.css" type="text/css"></head><body><script defer src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script><script defer src="/task/js/ui/fireworks.js"></script><canvas class="fireworks"></canvas><div class="container"><a class="sidebar-toggle hty-icon-button" id="menu-btn"><div class="hamburger hamburger--spin" type="button"><span class="hamburger-box"><span class="hamburger-inner"></span></span></div></a><div class="sidebar-toggle sidebar-overlay"></div><aside class="sidebar"><script src="/task/js/sidebar.js"></script><ul class="sidebar-nav"><li class="sidebar-nav-item sidebar-nav-toc hty-icon-button sidebar-nav-active" data-target="post-toc-wrap" title="文章目录"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-list-ordered"></use></svg></li><li class="sidebar-nav-item sidebar-nav-overview hty-icon-button" data-target="site-overview-wrap" title="站点概览"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-passport-line"></use></svg></li></ul><div class="sidebar-panel" id="site-overview-wrap"><div class="site-info fix-top"><a class="site-author-avatar" href="/task/about/" title="爱肖彤真是太好了"><img width="96" loading="lazy" src="/task/Yun.png" alt="爱肖彤真是太好了"></a><div class="site-author-name"><a href="/task/about/">爱肖彤真是太好了</a></div><a class="site-name" href="/task/about/site.html">工藤旧二の博客</a><sub class="site-subtitle"></sub><div class="site-desciption"></div></div><nav class="site-state"><a class="site-state-item hty-icon-button icon-home" href="/task/" title="首页"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-home-4-line"></use></svg></span></a><div class="site-state-item"><a href="/task/archives/" title="归档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-archive-line"></use></svg></span><span class="site-state-item-count">57</span></a></div><div class="site-state-item"><a href="/task/categories/" title="分类"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-2-line"></use></svg></span><span class="site-state-item-count">2</span></a></div><div class="site-state-item"><a href="/task/tags/" title="标签"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="site-state-item-count">50</span></a></div><a class="site-state-item hty-icon-button" target="_blank" rel="noopener" href="https://yun.yunyoujun.cn" title="文档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-settings-line"></use></svg></span></a></nav><hr style="margin-bottom:0.5rem"><div class="links-of-author"><a class="links-of-author-item hty-icon-button" rel="noopener" title="RSS" target="_blank" style="color:orange"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-rss-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="QQ" target="_blank" style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="GitHub" target="_blank" style="color:#6e5494"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-github-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="微博" target="_blank" style="color:#E6162D"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-weibo-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="豆瓣" target="_blank" style="color:#007722"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-douban-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://music.163.com/#/user/home?id=552858287" title="网易云音乐" target="_blank" style="color:#C20C0C"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-netease-cloud-music-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="知乎" target="_blank" style="color:#0084FF"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-zhihu-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://space.bilibili.com/15081363" title="哔哩哔哩" target="_blank" style="color:#FF8EB3"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-bilibili-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Twitter" target="_blank" style="color:#1da1f2"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-twitter-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Telegram Channel" target="_blank" style="color:#0088CC"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-telegram-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="E-Mail" target="_blank" style="color:#8E71C1"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-mail-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Travelling" target="_blank" style="color:var(--hty-text-color)"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-send-plane-2-line"></use></svg></a></div><hr style="margin:0.5rem 1rem"><div class="links"><a class="links-item hty-icon-button" href="/task/links/" title="我的小伙伴们" style="color:dodgerblue"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-genderless-line"></use></svg></a></div><br><a class="links-item hty-icon-button" id="toggle-mode-btn" href="javascript:;" title="Mode" style="color: #f1cb64"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-contrast-2-line"></use></svg></a></div><div class="sidebar-panel sidebar-panel-active" id="post-toc-wrap"><div class="post-toc"><div class="post-toc-content"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%A5%E9%97%A8"><span class="toc-text">入门</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%AE%89%E8%A3%85%E5%9F%BA%E7%A1%80%E4%BE%9D%E8%B5%96"><span class="toc-text">安装基础依赖</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1"><span class="toc-text">启动服务</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BA%A4%E4%BA%92%E5%BC%8Fapi%E6%96%87%E6%A1%A3"><span class="toc-text">交互式api文档</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#fastapi%E7%9A%84%E5%BC%82%E6%AD%A5%E5%A4%84%E7%90%86"><span class="toc-text">fastapi的异步处理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#async"><span class="toc-text">async</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#async-loop-run-in-executor"><span class="toc-text">async+loop.run_in_executor</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#async-await"><span class="toc-text">async+await</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#def"><span class="toc-text">def</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%E6%A0%A1%E9%AA%8C"><span class="toc-text">数据格式校验</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%B7%AF%E5%BE%84"><span class="toc-text">路径</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%82%E6%95%B0"><span class="toc-text">参数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%E5%8F%8A%E9%BB%98%E8%AE%A4%E5%80%BC"><span class="toc-text">可选参数及默认值</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%83%E5%B0%94%E5%80%BC%E5%8F%82%E6%95%B0"><span class="toc-text">布尔值参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A4%9A%E8%B7%AF%E5%BE%84%E5%92%8C%E5%8F%82%E6%95%B0"><span class="toc-text">多路径和参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E4%BD%93-%E8%B7%AF%E5%BE%84%E5%8F%82%E6%95%B0-%E6%9F%A5%E8%AF%A2%E5%8F%82%E6%95%B0"><span class="toc-text">请求体+路径参数+查询参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A4%9A%E8%AF%B7%E6%B1%82%E4%BD%93%E5%8F%82%E6%95%B0"><span class="toc-text">多请求体参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A6%82%E6%9E%9C%E6%83%B3%E8%A6%81%E5%9C%A8%E5%A4%9A%E8%AF%B7%E6%B1%82%E4%BD%93%E5%8F%82%E6%95%B0%E5%90%8E%E5%8A%A0%E5%8D%95%E4%B8%80%E5%8F%82%E6%95%B0"><span class="toc-text">如果想要在多请求体参数后加单一参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B5%8C%E5%85%A5%E5%8D%95%E4%B8%AA%E8%AF%B7%E6%B1%82%E4%BD%93%E5%8F%82%E6%95%B0"><span class="toc-text">嵌入单个请求体参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B5%8C%E5%A5%97%E5%8F%82%E6%95%B0"><span class="toc-text">嵌套参数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%BB%E6%84%8F-dict-%E6%9E%84%E6%88%90%E7%9A%84%E8%AF%B7%E6%B1%82%E4%BD%93"><span class="toc-text">任意 dict 构成的请求体</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99"><span class="toc-text">校验规则</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Query"><span class="toc-text">Query</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Path"><span class="toc-text">Path</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Body"><span class="toc-text">Body</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Field"><span class="toc-text">Field</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Cookie"><span class="toc-text">Cookie</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Headers"><span class="toc-text">Headers</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Form"><span class="toc-text">Form</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%93%8D%E5%BA%94%E6%A8%A1%E5%9E%8B"><span class="toc-text">响应模型</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#response-model-include-set-%E5%8C%85%E5%90%AB%E9%9C%80%E8%A6%81%E5%B1%95%E7%A4%BA%E7%9A%84%E5%AD%97%E6%AE%B5"><span class="toc-text">response_model_include   set 包含需要展示的字段</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#response-model-exclude-set-%E5%8C%85%E5%90%AB%E9%9C%80%E8%A6%81%E5%8E%BB%E9%99%A4%E5%B1%95%E7%A4%BA%E7%9A%84%E5%AD%97%E6%AE%B5"><span class="toc-text">response_model_exclude  set 包含需要去除展示的字段</span></a></li></ol></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Union-%E6%88%96%E8%80%85-anyOf"><span class="toc-text">Union 或者 anyOf</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%90%88%E5%B9%B6%E9%A2%84%E5%AE%9Aresponse"><span class="toc-text">合并预定response</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%93%8D%E5%BA%94%E7%8A%B6%E6%80%81%E7%A0%81"><span class="toc-text">响应状态码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%86%85%E7%BD%AE%E7%9A%84Json%E8%A7%A3%E6%9E%90"><span class="toc-text">内置的Json解析</span></a></li></ol></div></div></div></aside><main class="sidebar-translate" id="content"><div id="post"><article class="post-block" itemscope itemtype="https://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://huang_zhao.gitee.io/task/task/2021/07/02/python/%E6%A1%86%E6%9E%B6/fast-api/fastapi%20%E5%9F%BA%E7%A1%80/"><span hidden itemprop="author" itemscope itemtype="https://schema.org/Person"><meta itemprop="name" content="爱肖彤真是太好了"><meta itemprop="description"></span><span hidden itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><meta itemprop="name" content="工藤旧二の博客"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">fastapi基础</h1><div class="post-meta"><div class="post-time" style="display:block"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-line"></use></svg></span> <time title="创建时间：2021-07-02 13:33:43" itemprop="dateCreated datePublished" datetime="2021-07-02T13:33:43+08:00">2021-07-02</time><span class="post-meta-divider">-</span><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-2-line"></use></svg></span> <time title="修改时间：2021-07-01 14:11:51" itemprop="dateModified" datetime="2021-07-01T14:11:51+08:00">2021-07-01</time></div><span class="post-count"><span class="post-symbolcount"><span class="post-meta-item-icon" title="本文字数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-file-word-line"></use></svg></span> <span title="本文字数">3.4k</span><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读时长"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-timer-line"></use></svg></span> <span title="阅读时长">15m</span></span></span><span class="post-busuanzi"><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读次数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg> <span id="busuanzi_value_page_pv"></span></span></span><div class="post-classify"><span class="post-category"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-line"></use></svg></span> <span itemprop="about" itemscope itemtype="https://schema.org/Thing"><a class="category" href="/task/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/" style="--text-color:var(--hty-text-color)" itemprop="url" rel="index"><span itemprop="text">技术分享</span></a></span></span><span class="post-tag"><span class="post-meta-divider">-</span><a class="tag" href="/task/tags/python/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">python</span></a><a class="tag" href="/task/tags/%E6%A1%86%E6%9E%B6/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">框架</span></a><a class="tag" href="/task/tags/fastapi/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">fastapi</span></a></span></div></div></header><section class="post-body" itemprop="articleBody"><div class="post-content markdown-body" style="--smc-primary:#0078E7;"><h3 id="入门"><a href="#入门" class="headerlink" title="入门"></a>入门</h3><h5 id="安装基础依赖"><a href="#安装基础依赖" class="headerlink" title="安装基础依赖"></a>安装基础依赖</h5><pre><code>pip install fastapi</code></pre>
<p>并且安装<code>uvicorn</code>来作为服务器：</p>
<pre><code>pip install uvicorn[standard]</code></pre>
<p>然后对你想使用的每个可选依赖项也执行相同的操作</p>
<h5 id="启动服务"><a href="#启动服务" class="headerlink" title="启动服务"></a>启动服务</h5><pre><code>uvicorn main:app --reload</code></pre>
<p><code>uvicorn main:app</code> 命令含义如下:</p>
<ul>
<li><code>main</code>：<code>main.py</code> 文件（一个 Python「模块」）。</li>
<li><code>app</code>：在 <code>main.py</code> 文件中通过 <code>app = FastAPI()</code> 创建的对象。</li>
<li><code>--reload</code>：让服务器在更新代码后重新启动。仅在开发时使用该选项。</li>
</ul>
<h5 id="交互式api文档"><a href="#交互式api文档" class="headerlink" title="交互式api文档"></a>交互式api文档</h5><p><a target="_blank" rel="noopener" href="http://127.0.0.1:8000/docs">http://127.0.0.1:8000/docs</a></p>
<p>备选api文档：<a target="_blank" rel="noopener" href="http://127.0.0.1:8000/redoc">http://127.0.0.1:8000/redoc</a></p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">class</span> <span class="token class-name">Item</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    name<span class="token punctuation">:</span> str
      <span class="token comment" spellcheck="true"># field中的example会覆盖docs上的示例，也会被config覆盖</span>
    description<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Field<span class="token punctuation">(</span>
        None<span class="token punctuation">,</span> title<span class="token operator">=</span><span class="token string">"The description of the item"</span><span class="token punctuation">,</span> max_length<span class="token operator">=</span><span class="token number">300</span><span class="token punctuation">,</span> example<span class="token operator">=</span><span class="token string">"描述"</span>
    <span class="token punctuation">)</span>
    price<span class="token punctuation">:</span> float <span class="token operator">=</span> Field<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span> gt<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span> description<span class="token operator">=</span><span class="token string">"The price must be greater than zero"</span><span class="token punctuation">)</span>
    tax<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>float<span class="token punctuation">]</span> <span class="token operator">=</span> None

    <span class="token keyword">class</span> <span class="token class-name">Config</span><span class="token punctuation">:</span>
      <span class="token comment" spellcheck="true"># 会自动覆盖展示在docs上的示例</span>
        schema_extra <span class="token operator">=</span> <span class="token punctuation">{</span>
                <span class="token string">"example"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
                    <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
                    <span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"A very nice Item"</span><span class="token punctuation">,</span>
                    <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">35.4</span><span class="token punctuation">,</span>
                    <span class="token string">"tax"</span><span class="token punctuation">:</span> <span class="token number">3.2</span><span class="token punctuation">,</span>
                <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>

@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">update_item</span><span class="token punctuation">(</span>
    item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span>
    item<span class="token punctuation">:</span> Item <span class="token operator">=</span> Body<span class="token punctuation">(</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span>
        example<span class="token operator">=</span><span class="token punctuation">{</span>
            <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
            <span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"A very nice Item"</span><span class="token punctuation">,</span>
            <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">35.4</span><span class="token punctuation">,</span>
            <span class="token string">"tax"</span><span class="token punctuation">:</span> <span class="token number">3.2</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">:</span>
    results <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"item"</span><span class="token punctuation">:</span> item<span class="token punctuation">}</span>
    <span class="token keyword">return</span> results
</code></pre>
<h3 id="fastapi的异步处理"><a href="#fastapi的异步处理" class="headerlink" title="fastapi的异步处理"></a>fastapi的异步处理</h3><pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI
<span class="token keyword">import</span> time
<span class="token keyword">import</span> asyncio
<span class="token keyword">import</span> os

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>

@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/async_slowest"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">async_slowest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
   time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
   <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"async mode but use sync sleep"</span><span class="token punctuation">}</span>

@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/async_sleep_in_thread"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">async_sleep_in_thread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
   loop <span class="token operator">=</span> asyncio<span class="token punctuation">.</span>get_event_loop<span class="token punctuation">(</span><span class="token punctuation">)</span>
   <span class="token keyword">await</span> loop<span class="token punctuation">.</span>run_in_executor<span class="token punctuation">(</span>None<span class="token punctuation">,</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
   <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"sleep run in thread pool"</span><span class="token punctuation">}</span>

@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/async_sleep"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">async_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
   <span class="token keyword">await</span> asyncio<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
   <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"async mode sleep"</span><span class="token punctuation">}</span>

@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/sync"</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">sync_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
   time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
   <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"sync, but run in thread pool"</span><span class="token punctuation">}</span>

</code></pre>
<p>我们用ab工具，总量100，并发100进行测试。</p>
<h4 id="async"><a href="#async" class="headerlink" title="async"></a>async</h4><p>这4个函数，最慢的就是第一个async_slowest。<br>我们可以看到，它几乎是一个接一个的串联输出。<br>原因是：<br>fastapi框架会将async函数会放到event loop中运行。<br>如果函数没有运行或有await，则其他函数无法运行。<br>所以这里是一个串联的效果，总时间需要100s</p>
<h4 id="async-loop-run-in-executor"><a href="#async-loop-run-in-executor" class="headerlink" title="async+loop.run_in_executor"></a>async+loop.run_in_executor</h4><p>为了解决这个问题，第二个函数引入了loop.run_in_executor<br>loop = asyncio.get_event_loop()<br>可以获取当前的event loop<br>loop.run_in_executor(None, time.sleep, 1)<br>是将time.sleep(1)放到一个线程池中去运行，所以不会出现阻塞。<br>这个函数，1秒可以全部运行完。</p>
<h4 id="async-await"><a href="#async-await" class="headerlink" title="async+await"></a>async+await</h4><p>第三个函数是最正宗的实现。<br>它使用异步的sleep取代了原版同步的sleep。<br>这也是最快的实现。<br>1秒可以运行完</p>
<h4 id="def"><a href="#def" class="headerlink" title="def"></a>def</h4><p>第四个函数是唯一一个不是async的普通函数。<br>它的运行时间是多少呢？<br>我的电脑是3秒运行完！<br>为什么？<br>这就是fastapi精彩的地方。<br>前面提到，async函数会放到event loop中执行。<br>那么，普通的函数会放到哪里呢？<br>答案是，放到thread pool中。<br>那么为什么是3秒呢。<br>这是因为我的电脑是逻辑8核。线程池的默认配置是核数*5，所以是40线程。<br>我的测试是100个并发，所以一共是3秒完成。<br>40-&gt;40-&gt;20</p>
<p>总结：简单的说，就像官方所说，如果你不清楚你函数里的调用是否异步，那就定义为普通函数。因为它可以采用多线程的方式解决。<br>反之，定义了async函数，里面却是同步的调用（第一个函数），那么这将慢的是灾难！</p>
<h3 id="数据格式校验"><a href="#数据格式校验" class="headerlink" title="数据格式校验"></a>数据格式校验</h3><p> <a target="_blank" rel="noopener" href="https://pydantic-docs.helpmanual.io/">Pydantic</a> </p>
<p>额外的数据类型 <a target="_blank" rel="noopener" href="https://fastapi.tiangolo.com/zh/tutorial/extra-data-types/">https://fastapi.tiangolo.com/zh/tutorial/extra-data-types/</a>   日期，uuid，byte</p>
<h3 id="路径"><a href="#路径" class="headerlink" title="路径"></a>路径</h3><p>注意若前缀相同，可选参数应在默认路径之下，如下顺序不能互换</p>
<p>否则，<code>/users/&#123;user_id&#125;</code> 的路径还将与 <code>/users/me</code> 相匹配，”认为”自己正在接收一个值为 <code>&quot;me&quot;</code> 的 <code>user_id</code> 参数。</p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/users/me"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_user_me</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"user_id"</span><span class="token punctuation">:</span> <span class="token string">"the current user"</span><span class="token punctuation">}</span>


@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/users/{user_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_user</span><span class="token punctuation">(</span>user_id<span class="token punctuation">:</span> str<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"user_id"</span><span class="token punctuation">:</span> user_id<span class="token punctuation">}</span></code></pre>
<p>:path作为参数的类型表示可以接受任意参数，可用于404页面，用于文件路径</p>
<p>由于OpenApi不支持在路径参数中携带斜杠，因为这样会导致歧义，所以可以用Starlette 的一个内部工具在 <strong>FastAPI</strong> 中实现它</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/{path:path}"</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">not_found</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token number">123</span></code></pre>
<h3 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h3><h4 id="可选参数及默认值"><a href="#可选参数及默认值" class="headerlink" title="可选参数及默认值"></a>可选参数及默认值</h4><p>Optional表示这个参数是某个类型的可选参数，后面可以携带默认值</p>
<pre class=" language-Python"><code class="language-Python">q: Optional[str] = None</code></pre>
<h4 id="布尔值参数"><a href="#布尔值参数" class="headerlink" title="布尔值参数"></a>布尔值参数</h4><p>0,false,False,no 都是false</p>
<p>1,true,True,yes都是true</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">read_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> q<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None<span class="token punctuation">,</span>short<span class="token punctuation">:</span>bool <span class="token operator">=</span> <span class="token boolean">False</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"q"</span><span class="token punctuation">:</span> q<span class="token punctuation">,</span><span class="token string">"short"</span><span class="token punctuation">:</span>short<span class="token punctuation">}</span></code></pre>
<h4 id="多路径和参数"><a href="#多路径和参数" class="headerlink" title="多路径和参数"></a>多路径和参数</h4><pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/users/{user_id}/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_user_item</span><span class="token punctuation">(</span>
    user_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item_id<span class="token punctuation">:</span> str<span class="token punctuation">,</span> q<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None<span class="token punctuation">,</span> short<span class="token punctuation">:</span> bool <span class="token operator">=</span> <span class="token boolean">False</span>
<span class="token punctuation">)</span><span class="token punctuation">:</span>
    item <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"owner_id"</span><span class="token punctuation">:</span> user_id<span class="token punctuation">}</span>
    <span class="token keyword">if</span> q<span class="token punctuation">:</span>
        item<span class="token punctuation">.</span>update<span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token string">"q"</span><span class="token punctuation">:</span> q<span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token operator">not</span> short<span class="token punctuation">:</span>
        item<span class="token punctuation">.</span>update<span class="token punctuation">(</span>
            <span class="token punctuation">{</span><span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"This is an amazing item that has a long description"</span><span class="token punctuation">}</span>
        <span class="token punctuation">)</span>
    <span class="token keyword">return</span> item</code></pre>
<h4 id="请求体-路径参数-查询参数"><a href="#请求体-路径参数-查询参数" class="headerlink" title="请求体+路径参数+查询参数"></a>请求体+路径参数+查询参数</h4><p>路径参数在路径后</p>
<p>请求体为一个json</p>
<p>查询参数为一个query</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item<span class="token punctuation">:</span> Item<span class="token punctuation">,</span> q<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None<span class="token punctuation">)</span><span class="token punctuation">:</span>
    result <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token operator">**</span>item<span class="token punctuation">.</span>dict<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
    <span class="token keyword">if</span> q<span class="token punctuation">:</span>
        result<span class="token punctuation">.</span>update<span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token string">"q"</span><span class="token punctuation">:</span> q<span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> result</code></pre>
<h4 id="多请求体参数"><a href="#多请求体参数" class="headerlink" title="多请求体参数"></a>多请求体参数</h4><p>注意和单请求体区分，多请求体的中一个请求体的key会显示出来</p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">class</span> <span class="token class-name">Item</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    name<span class="token punctuation">:</span> str <span class="token operator">=</span> None
    price<span class="token punctuation">:</span> float <span class="token operator">=</span> None
    is_offer<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>bool<span class="token punctuation">]</span> <span class="token operator">=</span> None


<span class="token keyword">class</span> <span class="token class-name">User</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    username<span class="token punctuation">:</span> str
    full_name<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None


@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">update_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item<span class="token punctuation">:</span> Item<span class="token punctuation">,</span> user<span class="token punctuation">:</span> User<span class="token punctuation">)</span><span class="token punctuation">:</span>
    results <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"item"</span><span class="token punctuation">:</span> item<span class="token punctuation">,</span> <span class="token string">"user"</span><span class="token punctuation">:</span> user<span class="token punctuation">}</span>
    <span class="token keyword">return</span> results

<span class="token comment" spellcheck="true"># 请求体参数</span>
<span class="token punctuation">{</span>
  <span class="token string">"item_id"</span><span class="token punctuation">:</span> <span class="token number">123</span><span class="token punctuation">,</span>
  <span class="token string">"item"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
    <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"string"</span><span class="token punctuation">,</span>
    <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token string">"is_offer"</span><span class="token punctuation">:</span> true
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
    <span class="token string">"username"</span><span class="token punctuation">:</span> <span class="token string">"hz"</span><span class="token punctuation">,</span>
    <span class="token string">"full_name"</span><span class="token punctuation">:</span> null
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="如果想要在多请求体参数后加单一参数"><a href="#如果想要在多请求体参数后加单一参数" class="headerlink" title="如果想要在多请求体参数后加单一参数"></a>如果想要在多请求体参数后加单一参数</h4><pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">update_item</span><span class="token punctuation">(</span>
    item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item<span class="token punctuation">:</span> Item<span class="token punctuation">,</span> user<span class="token punctuation">:</span> User<span class="token punctuation">,</span> importance<span class="token punctuation">:</span> int <span class="token operator">=</span> Body<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">:</span>
    results <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"item"</span><span class="token punctuation">:</span> item<span class="token punctuation">,</span> <span class="token string">"user"</span><span class="token punctuation">:</span> user<span class="token punctuation">,</span> <span class="token string">"importance"</span><span class="token punctuation">:</span> importance<span class="token punctuation">}</span>
    <span class="token keyword">return</span> results

<span class="token comment" spellcheck="true"># 请求体参数</span>
<span class="token punctuation">{</span>
    <span class="token string">"item"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
        <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
        <span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"The pretender"</span><span class="token punctuation">,</span>
        <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">42.0</span><span class="token punctuation">,</span>
        <span class="token string">"tax"</span><span class="token punctuation">:</span> <span class="token number">3.2</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
        <span class="token string">"username"</span><span class="token punctuation">:</span> <span class="token string">"dave"</span><span class="token punctuation">,</span>
        <span class="token string">"full_name"</span><span class="token punctuation">:</span> <span class="token string">"Dave Grohl"</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token string">"importance"</span><span class="token punctuation">:</span> <span class="token number">5</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="嵌入单个请求体参数"><a href="#嵌入单个请求体参数" class="headerlink" title="嵌入单个请求体参数"></a>嵌入单个请求体参数</h4><p>单个请求体参数是没有key的，如果我们非要给他加上key，Body提供一个可处理的参数</p>
<pre class=" language-python"><code class="language-python">item<span class="token punctuation">:</span> Item <span class="token operator">=</span> Body<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span> embed<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span></code></pre>
<p>例子</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">update_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item<span class="token punctuation">:</span> Item <span class="token operator">=</span> Body<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span> embed<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    results <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"item"</span><span class="token punctuation">:</span> item<span class="token punctuation">}</span>
    <span class="token keyword">return</span> results

<span class="token comment" spellcheck="true">#请求体参数</span>
<span class="token punctuation">{</span>
    <span class="token string">"item"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span>
        <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
        <span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"The pretender"</span><span class="token punctuation">,</span>
        <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">42.0</span><span class="token punctuation">,</span>
        <span class="token string">"tax"</span><span class="token punctuation">:</span> <span class="token number">3.2</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="嵌套参数"><a href="#嵌套参数" class="headerlink" title="嵌套参数"></a>嵌套参数</h4><p>可以嵌套任意深度的模型</p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> typing <span class="token keyword">import</span> List<span class="token punctuation">,</span> Optional<span class="token punctuation">,</span> Set

<span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI
<span class="token keyword">from</span> pydantic <span class="token keyword">import</span> BaseModel<span class="token punctuation">,</span> HttpUrl

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


<span class="token keyword">class</span> <span class="token class-name">Image</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    url<span class="token punctuation">:</span> HttpUrl
    name<span class="token punctuation">:</span> str


<span class="token keyword">class</span> <span class="token class-name">Item</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    name<span class="token punctuation">:</span> str
    description<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None
    price<span class="token punctuation">:</span> float
    tax<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>float<span class="token punctuation">]</span> <span class="token operator">=</span> None
    tags<span class="token punctuation">:</span> Set<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> set<span class="token punctuation">(</span><span class="token punctuation">)</span>
    images<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>List<span class="token punctuation">[</span>Image<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> None


@app<span class="token punctuation">.</span>put<span class="token punctuation">(</span><span class="token string">"/items/{item_id}"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">update_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> int<span class="token punctuation">,</span> item<span class="token punctuation">:</span> Item<span class="token punctuation">)</span><span class="token punctuation">:</span>
    results <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">"item_id"</span><span class="token punctuation">:</span> item_id<span class="token punctuation">,</span> <span class="token string">"item"</span><span class="token punctuation">:</span> item<span class="token punctuation">}</span>
    <span class="token keyword">return</span> results


<span class="token comment" spellcheck="true"># 请求体</span>
<span class="token punctuation">{</span>
    <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
    <span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"The pretender"</span><span class="token punctuation">,</span>
    <span class="token string">"price"</span><span class="token punctuation">:</span> <span class="token number">42.0</span><span class="token punctuation">,</span>
    <span class="token string">"tax"</span><span class="token punctuation">:</span> <span class="token number">3.2</span><span class="token punctuation">,</span>
    <span class="token string">"tags"</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>
        <span class="token string">"rock"</span><span class="token punctuation">,</span>
        <span class="token string">"metal"</span><span class="token punctuation">,</span>
        <span class="token string">"bar"</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>

    <span class="token string">"images"</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>

        <span class="token punctuation">{</span>
            <span class="token string">"url"</span><span class="token punctuation">:</span> <span class="token string">"http://example.com/baz.jpg"</span><span class="token punctuation">,</span>
            <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"The Foo live"</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{</span>
            <span class="token string">"url"</span><span class="token punctuation">:</span> <span class="token string">"http://example.com/dave.jpg"</span><span class="token punctuation">,</span>
            <span class="token string">"name"</span><span class="token punctuation">:</span> <span class="token string">"The Baz"</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="任意-dict-构成的请求体"><a href="#任意-dict-构成的请求体" class="headerlink" title="任意 dict 构成的请求体"></a>任意 <code>dict</code> 构成的请求体</h4><pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> typing <span class="token keyword">import</span> Dict

<span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


@app<span class="token punctuation">.</span>post<span class="token punctuation">(</span><span class="token string">"/index-weights/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_index_weights</span><span class="token punctuation">(</span>weights<span class="token punctuation">:</span> Dict<span class="token punctuation">[</span>int<span class="token punctuation">,</span> float<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> weights</code></pre>
<p>tips</p>
<p>请记住 JSON 仅支持将 <code>str</code> 作为键。</p>
<p>但是 Pydantic 具有自动转换数据的功能。</p>
<p>这意味着，即使你的 API 客户端只能将字符串作为键发送，只要这些字符串内容仅包含整数，Pydantic 就会对其进行转换并校验。</p>
<p>然后你接收的名为 <code>weights</code> 的 <code>dict</code> 实际上将具有 <code>int</code> 类型的键和 <code>float</code> 类型的值。</p>
<h3 id="校验规则"><a href="#校验规则" class="headerlink" title="校验规则"></a>校验规则</h3><p>实际上，<code>Query</code>、<code>Path</code> 和其他你将在之后看到的类，创建的是由一个共同的 <code>Params</code> 类派生的子类的对象，该共同类本身又是 Pydantic 的 <code>FieldInfo</code> 类的子类。</p>
<p>Pydantic 的 <code>Field</code> 也会返回一个 <code>FieldInfo</code> 的实例。</p>
<p><code>Body</code> 也直接返回 <code>FieldInfo</code> 的一个子类的对象。还有其他一些你之后会看到的类是 <code>Body</code> 类的子类。</p>
<p>请记住当你从 <code>fastapi</code> 导入 <code>Query</code>、<code>Path</code> 等对象时，他们实际上是返回特殊类的函数。</p>
<h4 id="Query"><a href="#Query" class="headerlink" title="Query"></a>Query</h4><p>校验在？后的参数</p>
<p>通用的校验和元数据：</p>
<ul>
<li><code>alias</code> 别名</li>
<li><code>title</code></li>
<li><code>description</code></li>
<li><code>deprecated</code>  是否显示弃用（默认false）</li>
</ul>
<p>特定于字符串的校验：</p>
<ul>
<li><code>min_length</code></li>
<li><code>max_length</code></li>
<li><code>regex </code>  正则匹配</li>
</ul>
<p>完整实例用法</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_item</span><span class="token punctuation">(</span>q<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Query<span class="token punctuation">(</span>
        None<span class="token punctuation">,</span>
        title<span class="token operator">=</span><span class="token string">"参数q"</span><span class="token punctuation">,</span>
        description<span class="token operator">=</span><span class="token string">"参数q的描述"</span><span class="token punctuation">,</span>
        min_length<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">,</span>
        max_length<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">,</span>
        alias<span class="token operator">=</span><span class="token string">"items-q"</span><span class="token punctuation">,</span>
        regex<span class="token operator">=</span><span class="token string">"^f"</span><span class="token punctuation">,</span>
        deprecated<span class="token operator">=</span><span class="token boolean">True</span>
    <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> q
</code></pre>
<p>fastapi自带有参数格式校验规则，暂时只校验参数的格式，但是返回格式不是我们自定义的</p>
<pre class=" language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"detail"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">"loc"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
                <span class="token string">"body"</span><span class="token punctuation">,</span>
                <span class="token string">"price"</span>
            <span class="token punctuation">]</span><span class="token punctuation">,</span>
            <span class="token property">"msg"</span><span class="token operator">:</span> <span class="token string">"value is not a valid float"</span><span class="token punctuation">,</span>
            <span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"type_error.float"</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre>
<p>如果想要校验例如参数的最大长度等可以使用fastapi自带的Query</p>
<p>Query的第一个参数可用于设定默认值，当使用query设定默认值后，这个参数也会变成可选参数，所以optional实际上就没有用了</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_item</span><span class="token punctuation">(</span>q<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Query<span class="token punctuation">(</span>None<span class="token punctuation">,</span> min_length<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">,</span> max_length<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> regex<span class="token operator">=</span><span class="token string">"^fixedquery$"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> q</code></pre>
<p>这个指定的正则表达式通过以下规则检查接收到的参数值：</p>
<ul>
<li><code>^</code>：以该符号之后的字符开头，符号之前没有字符。</li>
<li><code>fixedquery</code>: 值精确地等于 <code>fixedquery</code>。</li>
<li><code>$</code>: 到此结束，在 <code>fixedquery</code> 之后没有更多字符。</li>
</ul>
<p>如果我们又要使用query又要让这个参数为<strong>必填参数</strong>可以使用三个点作为query的第一个参数</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_item</span><span class="token punctuation">(</span>q<span class="token punctuation">:</span>str <span class="token operator">=</span> Query<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">,</span> min_length<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">,</span> max_length<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> regex<span class="token operator">=</span><span class="token string">"^fixedquery$"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> q</code></pre>
<pre class=" language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"detail"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">"loc"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
                <span class="token string">"query"</span><span class="token punctuation">,</span>
                <span class="token string">"q"</span>
            <span class="token punctuation">]</span><span class="token punctuation">,</span>
            <span class="token property">"msg"</span><span class="token operator">:</span> <span class="token string">"ensure this value has at most 10 characters"</span><span class="token punctuation">,</span>
            <span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"value_error.any_str.max_length"</span><span class="token punctuation">,</span>
            <span class="token property">"ctx"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
                <span class="token property">"limit_value"</span><span class="token operator">:</span> <span class="token number">10</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="Path"><a href="#Path" class="headerlink" title="Path"></a>Path</h4><p>校验路径参数</p>
<p>对元数据扩展，和参数校验比query更多</p>
<ul>
<li>ge大于等于   gt大于   le 小于等于   lt 小于（适用于int和float）</li>
</ul>
<h4 id="Body"><a href="#Body" class="headerlink" title="Body"></a>Body</h4><p>和path的校验参数相同，校验的是body体中的数据</p>
<h4 id="Field"><a href="#Field" class="headerlink" title="Field"></a>Field</h4><p>字段校验，校验规则和Body，Path相同</p>
<p>field不仅可以校验对象中的类型，也可以用于参数校验</p>
<p>注意，<code>Field</code> 是直接从 <code>pydantic</code> 导入的，而不是像其他的（<code>Query</code>，<code>Path</code>，<code>Body</code> 等）都从 <code>fastapi</code> 导入。</p>
<p>例子</p>
<pre class=" language-Python"><code class="language-Python">class Item(BaseModel):
    name: str
    description: Optional[str] = Field(
        None, title="The description of the item", max_length=300
    )
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results</code></pre>
<h4 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h4><p>cookie的校验和上述校验规则都相同</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_items</span><span class="token punctuation">(</span>ads_id<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Cookie<span class="token punctuation">(</span>None<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"ads_id"</span><span class="token punctuation">:</span> ads_id<span class="token punctuation">}</span></code></pre>
<h4 id="Headers"><a href="#Headers" class="headerlink" title="Headers"></a>Headers</h4><pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_items</span><span class="token punctuation">(</span>user_agent<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Header<span class="token punctuation">(</span>None<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"User-Agent"</span><span class="token punctuation">:</span> user_agent<span class="token punctuation">}</span></code></pre>
<p>请求头中会有一些参数是用减号-来连接的比如u-a，Python会自动转化这些参数</p>
<p>如果出于某些原因，你需要禁用下划线到连字符的自动转换，设置<code>Header</code>的参数 <code>convert_underscores</code> 为 <code>False</code>:</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_items</span><span class="token punctuation">(</span>
    strange_header<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> Header<span class="token punctuation">(</span>None<span class="token punctuation">,</span> convert_underscores<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"strange_header"</span><span class="token punctuation">:</span> strange_header<span class="token punctuation">}</span></code></pre>
<p>重复的请求头key</p>
<p>若存在多个x-token的请求头，在Python中可以通过list来接受</p>
<pre class=" language-python"><code class="language-python">@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"/items/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_items</span><span class="token punctuation">(</span>x_token<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>List<span class="token punctuation">[</span>str<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> Header<span class="token punctuation">(</span>None<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"X-Token values"</span><span class="token punctuation">:</span> x_token<span class="token punctuation">}</span></code></pre>
<h4 id="Form"><a href="#Form" class="headerlink" title="Form"></a>Form</h4><p>用于表单校验</p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI<span class="token punctuation">,</span> Form

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


@app<span class="token punctuation">.</span>post<span class="token punctuation">(</span><span class="token string">"/login/"</span><span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">login</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span> username<span class="token punctuation">:</span> str <span class="token operator">=</span> Form<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">,</span> password<span class="token punctuation">:</span> str <span class="token operator">=</span> Form<span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
     <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"username"</span><span class="token punctuation">:</span> username<span class="token punctuation">}</span></code></pre>
<h3 id="响应模型"><a href="#响应模型" class="headerlink" title="响应模型"></a>响应模型</h3><p>请求类型装饰器参数</p>
<p>tips  set不是必须，只是规范，使用其他类型也会被转成set，不影响</p>
<ul>
<li><h6 id="response-model-include-set-包含需要展示的字段"><a href="#response-model-include-set-包含需要展示的字段" class="headerlink" title="response_model_include   set 包含需要展示的字段"></a>response_model_include   set 包含需要展示的字段</h6></li>
<li><h6 id="response-model-exclude-set-包含需要去除展示的字段"><a href="#response-model-exclude-set-包含需要去除展示的字段" class="headerlink" title="response_model_exclude  set 包含需要去除展示的字段"></a>response_model_exclude  set 包含需要去除展示的字段</h6></li>
<li><p>response_model_exclude_unset=True  来仅返回显式设定的值</p>
</li>
</ul>
<p>这里非常类似java中关于po，vo，dto等类似概念，传输数据和响应数据及时是同样的数据结构，也应该有不同的数据校验规则，所以应该有多种数据库映射类</p>
<p>比如用户传入用户名，密码，都是明文，我们返回给用户必须是密文，而数据库保存的数据字段可能会更多，如上三种不同的数据类型</p>
<pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> typing <span class="token keyword">import</span> Optional

<span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI
<span class="token keyword">from</span> pydantic <span class="token keyword">import</span> BaseModel<span class="token punctuation">,</span> EmailStr

app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


<span class="token keyword">class</span> <span class="token class-name">UserIn</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    username<span class="token punctuation">:</span> str
    password<span class="token punctuation">:</span> str
    email<span class="token punctuation">:</span> EmailStr
    full_name<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None


<span class="token keyword">class</span> <span class="token class-name">UserOut</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    username<span class="token punctuation">:</span> str
    email<span class="token punctuation">:</span> EmailStr
    full_name<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>str<span class="token punctuation">]</span> <span class="token operator">=</span> None


@app<span class="token punctuation">.</span>post<span class="token punctuation">(</span><span class="token string">"/user/"</span><span class="token punctuation">,</span> response_model<span class="token operator">=</span>UserOut<span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">create_user</span><span class="token punctuation">(</span>user<span class="token punctuation">:</span> UserIn<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">return</span> user</code></pre>
<p>如果一张表中有很多字段，而我们只想返回有值的字段，可以使用参数response_model_exclude_unset=True</p>
<p>这样可以适用于某些场景，并不与上面这种响应模式冲突</p>
<pre class=" language-Python"><code class="language-Python">from typing import List, Optional

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: float = 10.5
    tags: List[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
    return items[item_id]</code></pre>
<h4 id="Union-或者-anyOf"><a href="#Union-或者-anyOf" class="headerlink" title="Union 或者 anyOf"></a>Union 或者 anyOf</h4><p>你可以将一个响应声明为两种类型的 <code>Union</code>，这意味着该响应将是两种类型中的任何一种。</p>
<p>定义一个 <a target="_blank" rel="noopener" href="https://pydantic-docs.helpmanual.io/usage/types/#unions"><code>Union</code></a> 类型时，首先包括最详细的类型，然后是不太详细的类型。在下面的示例中，更详细的 <code>PlaneItem</code> 位于 <code>Union[PlaneItem，CarItem]</code> 中的 <code>CarItem</code> 之前。</p>
<pre class=" language-Python"><code class="language-Python">from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem):
    type = "car"


class PlaneItem(BaseItem):
    type = "plane"
    size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
}


@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
    return items[item_id]</code></pre>
<p>常见的response对象，一般也就用JSONResponse</p>
<p><a target="_blank" rel="noopener" href="https://www.cnblogs.com/mazhiyong/p/13279543.html">https://www.cnblogs.com/mazhiyong/p/13279543.html</a></p>
<h4 id="合并预定response"><a href="#合并预定response" class="headerlink" title="合并预定response"></a>合并预定response</h4><pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> typing <span class="token keyword">import</span> Optional

<span class="token keyword">from</span> fastapi <span class="token keyword">import</span> FastAPI
<span class="token keyword">from</span> fastapi<span class="token punctuation">.</span>responses <span class="token keyword">import</span> FileResponse
<span class="token keyword">from</span> pydantic <span class="token keyword">import</span> BaseModel


<span class="token keyword">class</span> <span class="token class-name">Item</span><span class="token punctuation">(</span>BaseModel<span class="token punctuation">)</span><span class="token punctuation">:</span>
    id<span class="token punctuation">:</span> str
    value<span class="token punctuation">:</span> str


responses <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token number">404</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"Item not found"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token number">302</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"The item was moved"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token number">403</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">"description"</span><span class="token punctuation">:</span> <span class="token string">"Not enough privileges"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>


app <span class="token operator">=</span> FastAPI<span class="token punctuation">(</span><span class="token punctuation">)</span>


@app<span class="token punctuation">.</span>get<span class="token punctuation">(</span>
    <span class="token string">"/items/{item_id}"</span><span class="token punctuation">,</span>
    response_model<span class="token operator">=</span>Item<span class="token punctuation">,</span>
    responses<span class="token operator">=</span><span class="token punctuation">{</span><span class="token operator">**</span>responses<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">"content"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token string">"image/png"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span>
<span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">read_item</span><span class="token punctuation">(</span>item_id<span class="token punctuation">:</span> str<span class="token punctuation">,</span> img<span class="token punctuation">:</span> Optional<span class="token punctuation">[</span>bool<span class="token punctuation">]</span> <span class="token operator">=</span> None<span class="token punctuation">)</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> img<span class="token punctuation">:</span>
        <span class="token keyword">return</span> FileResponse<span class="token punctuation">(</span><span class="token string">"image.png"</span><span class="token punctuation">,</span> media_type<span class="token operator">=</span><span class="token string">"image/png"</span><span class="token punctuation">)</span>
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span><span class="token string">"id"</span><span class="token punctuation">:</span> <span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token string">"value"</span><span class="token punctuation">:</span> <span class="token string">"there goes my hero"</span><span class="token punctuation">}</span></code></pre>
<h3 id="响应状态码"><a href="#响应状态码" class="headerlink" title="响应状态码"></a>响应状态码</h3><p>在请求装饰器中带status_code参数表示该次请求的响应状态码</p>
<p><code>status_code</code> 也能够接收一个 <code>IntEnum</code> 类型，比如 Python 的 <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/http.html#http.HTTPStatus"><code>http.HTTPStatus</code></a></p>
<p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">https://developer.mozilla.org/en-US/docs/Web/HTTP/Status</a></p>
<p>你可以使用来自 <code>fastapi.status</code> 的便捷变量。</p>
<h3 id="内置的Json解析"><a href="#内置的Json解析" class="headerlink" title="内置的Json解析"></a>内置的Json解析</h3><pre class=" language-Python"><code class="language-Python">from datetime import datetime

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel


class Item(BaseModel):
    title: str
    timestamp: datetime
    description: str = None


app = FastAPI()


@app.put("/items/{id}")
def update_item(id: str, item: Item):
    json_compatible_item_data = jsonable_encoder(item)
print(json_compatible_item_data)</code></pre>
</div><div id="reward-container"><span class="hty-icon-button button-glow" id="reward-button" title="打赏" onclick="var qr = document.getElementById(&quot;qr&quot;); qr.style.display = (qr.style.display === &quot;none&quot;) ? &quot;block&quot; : &quot;none&quot;;"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-hand-coin-line"></use></svg></span><div id="reward-comment">点我就给你看点有意思的</div><div id="qr" style="display:none;"><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png" alt="支付宝" title="支付宝"></a><div><span style="color:#00A3EE"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-alipay-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg" alt="QQ 支付" title="QQ 支付"></a><div><span style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg" alt="微信支付" title="微信支付"></a><div><span style="color:#2DC100"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-wechat-pay-line"></use></svg></span></div></div></div></div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者：</strong>爱肖彤真是太好了</li><li class="post-copyright-link"><strong>本文链接：</strong><a href="http://huang_zhao.gitee.io/task/2021/07/02/python/%E6%A1%86%E6%9E%B6/fast-api/fastapi%20%E5%9F%BA%E7%A1%80/" title="fastapi基础">http://huang_zhao.gitee.io/task/2021/07/02/python/%E6%A1%86%E6%9E%B6/fast-api/fastapi%20%E5%9F%BA%E7%A1%80/</a></li><li class="post-copyright-license"><strong>版权声明：</strong>本博客所有文章除特别声明外，均默认采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="noopener" title="CC BY-NC-SA 4.0 "><svg class="icon"><use xlink:href="#icon-creative-commons-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-by-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-nc-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-sa-line"></use></svg></a> 许可协议。</li></ul></section></article><div class="post-nav"><div class="post-nav-item"><a class="post-nav-prev" href="/task/2021/07/02/python/%E6%A1%86%E6%9E%B6/fast-api/fastapi%E5%AD%90%E5%BA%94%E7%94%A8%E4%B8%8E%E4%BA%8B%E4%BB%B6/" rel="prev" title="fastapi子应用与事件"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-left-s-line"></use></svg><span class="post-nav-text">fastapi子应用与事件</span></a></div><div class="post-nav-item"><a class="post-nav-next" href="/task/2021/07/01/%E5%85%B6%E4%BB%96/rabbitmq/" rel="next" title="rabbitmq使用"><span class="post-nav-text">rabbitmq使用</span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-right-s-line"></use></svg></a></div></div></div></main><footer class="sidebar-translate" id="footer"><div class="copyright"><span>&copy; 2019 – 2022 </span><span class="with-love" id="animate"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-cloud-line"></use></svg></span><span class="author"> 爱肖彤真是太好了</span></div><div class="powered"><span>由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v5.1.1</span><span class="footer-separator">|</span><span>主题 - <a rel="noopener" href="https://github.com/YunYouJun/hexo-theme-yun" target="_blank"><span>Yun</span></a> v0.9.7</span></div><div class="live_time"><span>本博客已萌萌哒地运行</span><span id="display_live_time"></span><span class="moe-text">(●'◡'●)</span><script>function blog_live_time() {
  window.setTimeout(blog_live_time, 1000);
  const start = new Date('2019-04-12T00:00:00');
  const now = new Date();
  const timeDiff = (now.getTime() - start.getTime());
  const msPerMinute = 60 * 1000;
  const msPerHour = 60 * msPerMinute;
  const msPerDay = 24 * msPerHour;
  const passDay = Math.floor(timeDiff / msPerDay);
  const passHour = Math.floor((timeDiff % msPerDay) / 60 / 60 / 1000);
  const passMinute = Math.floor((timeDiff % msPerHour) / 60 / 1000);
  const passSecond = Math.floor((timeDiff % msPerMinute) / 1000);
  display_live_time.innerHTML = " " + passDay + " 天 " + passHour + " 小时 " + passMinute + " 分 " + passSecond + " 秒";
}
blog_live_time();
</script></div><div id="busuanzi"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><span id="busuanzi_container_site_uv" title="总访客量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-user-line"></use></svg></span><span id="busuanzi_value_site_uv"></span></span><span class="footer-separator">|</span><span id="busuanzi_container_site_pv" title="总访问量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg></span><span id="busuanzi_value_site_pv"></span></span></div></footer><a class="hty-icon-button" id="goUp" aria-label="back-to-top" href="#"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-up-s-line"></use></svg><svg class="progress-circle-container" viewBox="0 0 100 100"><circle class="progress-circle" id="progressCircle" cx="50" cy="50" r="48" fill="none" stroke="#0078E7" stroke-width="2" stroke-linecap="round"></circle></svg></a><a class="popup-trigger hty-icon-button icon-search" id="search" href="javascript:;" title="搜索"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-search-line"></use></svg></span></a><script>window.addEventListener("DOMContentLoaded", () => {
  // Handle and trigger popup window
  document.querySelector(".popup-trigger").addEventListener("click", () => {
    document.querySelector(".popup").classList.add("show");
    setTimeout(() => {
      document.querySelector(".search-input").focus();
    }, 100);
  });

  // Monitor main search box
  const onPopupClose = () => {
    document.querySelector(".popup").classList.remove("show");
  };

  document.querySelector(".popup-btn-close").addEventListener("click", () => {
    onPopupClose();
  });

  window.addEventListener("keyup", event => {
    if (event.key === "Escape") {
      onPopupClose();
    }
  });
});
</script><script src="/task/js/search/local-search.js" defer></script><div class="popup search-popup"><div class="search-header"><span class="popup-btn-close close-icon hty-icon-button"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-close-line"></use></svg></span></div><div class="search-input-container"><input class="search-input" id="local-search-input" type="text" placeholder="搜索..." value=""></div><div id="local-search-result"></div></div></div><script defer src="/task/js/utils.js"></script><script defer src="/task/js/hexo-theme-yun.js"></script></body></html>